home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MemoryHe.cpp
-
- Contains: MemoryHeap class implementation
-
- Owned by: Michael Burbidge, Jens Alfke
- Owned by: Jens Alfke
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <16> 10/24/95 jpa 1293441: Added slush-fund.
- <15> 8/4/95 DM Leak detection [1267956]
- <14> 6/7/95 jpa IsValidBlock calls hooks to check for
- prefix/suffix validity. [1256829]
- <13> 5/5/95 TJ jpa: Don't call hooks in nondebug build.
- <12> 5/4/95 jpa Support for finding largest free block
- [1235657] and validating memory ranges
- [1246077]
- <11> 12/20/94 jpa Fixed constructor typo that turned on
- fZapOnFree.
- <10> 12/5/94 jpa Nuked errant pragma lib_export's. [1195676]
- <9> 10/24/94 jpa Constness [1194286].
- <8> 9/29/94 RA 1189812: Mods for 68K build.
- <7> 9/14/94 jpa Eliminated dependencies on rest of OpenDoc.
- Added support for getting the heap of a
- block. [1186692]
- <6> 8/17/94 jpa Added support for walking heaps [1179567].
- <5> 8/8/94 jpa Zap old block after reallocate.
- <4> 8/2/94 jpa Fixed bug in BlockSize (wasn't calling
- hooks when it should)
- <3> 6/18/94 MB More initial SOM deployment
- <2> 6/10/94 MB Make it build
- <1> 6/9/94 MB first checked in
- <3> 5/26/94 MB #1162181: Fixed MMM integration bug
- <2> 5/9/94 MB #1162181: Changes necessary to install MMM.
- <1> 4/29/94 MB first checked in
- To Do:
- In Progress:
-
- */
-
- #ifndef _PLATFMEM_
- #include "PlatfMem.h"
- #endif
-
- #ifndef _MEMORYHE_
- #include "MemoryHe.h"
- #endif
-
- #ifndef _MEMHOOKS_
- #include "MemHooks.h"
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
-
- //========================================================================================
- // CLASS ODMemoryHook (MM_DEBUG only)
- //========================================================================================
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::ODMemoryHook
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook::ODMemoryHook()
- {
- fNextHook = fPreviousHook = this;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::~ODMemoryHook
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook::~ODMemoryHook()
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::operator new
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void* ODMemoryHook::operator new(SIZE_T size, MMHeapLocation src)
- {
- return PlatformAllocateBlock(size, src);
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::operator delete
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void ODMemoryHook::operator delete(void* ptr)
- {
- PlatformFreeBlock(ptr);
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::GetHeaderSize
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODBlockSize ODMemoryHook::GetHeaderSize()
- {
- return 0;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::AboutToAllocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODBlockSize ODMemoryHook::AboutToAllocate(ODBlockSize size) const
- {
- return size;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::DidAllocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *ODMemoryHook::DidAllocate(void* blk, ODBlockSize)
- {
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::AboutToBlockSize
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- const void *ODMemoryHook::AboutToBlockSize(const void* blk)
- {
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::AboutToFree
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *ODMemoryHook::AboutToFree(void* blk)
- {
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::AboutToRealloc
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void ODMemoryHook::AboutToRealloc(void* &, ODBlockSize &)
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::DidRealloc
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *ODMemoryHook::DidRealloc(void *oldBlk, void *blk, ODBlockSize)
- {
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::AboutToReset
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void ODMemoryHook::AboutToReset()
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::Comment
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void ODMemoryHook::Comment(const char*)
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // ODMemoryHook::GetType
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- long ODMemoryHook::GetType() const
- {
- return ODMemoryHook::kNoType;
- }
- #endif
-
-
- //========================================================================================
- // CLASS MemoryHookList (MM_DEBUG only)
- //========================================================================================
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::MemoryHookList
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHookList::MemoryHookList()
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::Add
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHookList::Add(ODMemoryHook* aMemoryHook)
- {
- // Add at the fEnd of the list by adding after the last hook in the list.
-
- ODMemoryHook* afterHook = fHead.fPreviousHook;
-
- aMemoryHook->fNextHook = afterHook->fNextHook;
- afterHook->fNextHook->fPreviousHook = aMemoryHook;
- aMemoryHook->fPreviousHook = afterHook;
- afterHook->fNextHook = aMemoryHook;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::Remove
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHookList::Remove(ODMemoryHook* aMemoryHook)
- {
- aMemoryHook->fPreviousHook->fNextHook = aMemoryHook->fNextHook;
- aMemoryHook->fNextHook->fPreviousHook = aMemoryHook->fPreviousHook;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::First
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook* MemoryHookList::First() const
- {
- ODMemoryHook *h = fHead.fNextHook;
- return h != &fHead ? h : NULL;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::Next
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook* MemoryHookList::After( ODMemoryHook *h ) const
- {
- h = h->fNextHook;
- return h != &fHead ? h : NULL;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::Previous
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook* MemoryHookList::Before( ODMemoryHook *h ) const
- {
- h = h->fPreviousHook;
- return h != &fHead ? h : NULL;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::Last
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODMemoryHook* MemoryHookList::Last() const
- {
- ODMemoryHook *h = fHead.fPreviousHook;
- return h != &fHead ? h : NULL;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHookList::~MemoryHookList
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHookList::~MemoryHookList()
- {
- for (ODMemoryHook *hook = First(); hook != NULL; hook = First())
- {
- Remove(hook);
- delete hook;
- }
- }
- #endif
-
-
- //========================================================================================
- // CLASS MemoryHeap
- //========================================================================================
-
- const char *MemoryHeap::kDefaultDescription = "Give this MemoryHeap a description";
- const char *MemoryHeap::kDeadHeapDescription = "Dead heap, dead heap, dead heap!";
- MemoryHeap *MemoryHeap::fHeapList; // Don't initialize!
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::ValidateMagicNumber (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
-
- #if MM_DEBUG
-
- #pragma segment HeapSeg
- MMBoolean MemoryHeap::ValidateMagicNumber( ) const /* Adkins -- made ValidateMagicNumber( ) const */
- {
- if( fMagicNumber != kMagicNumber ) {
- MM_WARN("Invalid magic number for heap %d -- is this a valid heap?",this);
- return kMMFalse;
- } else
- return kMMTrue;
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetFirstHeap
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHeap *MemoryHeap::GetFirstHeap()
- {
- return fHeapList;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::Allocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::Allocate(ODBlockSize size)
- {
- this->ValidateMagicNumber();
-
- ODBlockSize originalSize = size;
- #if MM_DEBUG
- size = this->CallAboutToAllocateHooks(size);
- #endif
-
- ODBlockSize allocatedSize;
- void *blk = this->DoAllocate( size, allocatedSize);
-
- if( blk==kMMNULL && originalSize<=fSlushFundAllocSizeLimit ) {
- // Free slush fund. Do not try again, let the caller know it ran out of memory.
- // But a little memory will now be available to make cleanup possible.
- MM_WARN( this->GetSlushFundSize()>0 ?"Out of memory. Freed slush fund."
- :"Out of memory, no slush fund. Oh, dear." );
- this->FreeSlushFund();
- }
-
- if (blk != kMMNULL)
- {
- if (fZapOnAllocate)
- PlatformZapMem(blk,allocatedSize,0xBBBBBBBB);
- fBytesAllocated += allocatedSize;
- fNumberAllocatedBlocks++;
- }
-
- #if MM_DEBUG
- blk = this->CallDidAllocateHooks(blk, size);
- #endif
-
- return blk;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::BlockSize
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODBlockSize MemoryHeap::BlockSize(const void *blk) const
- {
- this->ValidateMagicNumber();
-
- if (blk == NULL)
- return 0;
-
- #if MM_DEBUG
- if (fAutoValidation)
- this->ValidateAndReport((void*)blk);
-
- blk = ((MemoryHeap *) this)->CallAboutToBlockSizeHooks((void*)blk);
- #endif
-
- ODBlockSize size = this->DoBlockSize((void*)blk);
-
- #if MM_DEBUG
- size -= this->CallAboutToAllocateHooks(0); // Subtract hook pad size
- #endif
- return size;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::BytesAllocated
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- unsigned long MemoryHeap::BytesAllocated() const
- {
- this->ValidateMagicNumber();
-
- return fBytesAllocated;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::Free
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::Free(void* blk)
- {
- this->ValidateMagicNumber();
-
- if (blk == NULL)
- return;
-
- #if MM_DEBUG
- if (fAutoValidation)
- this->ValidateAndReport(blk);
-
- blk = this->CallAboutToFreeHooks(blk);
- #endif
-
- ODBlockSize allocatedSize = (ODBlockSize) this->DoBlockSize(blk);
-
- if (fZapOnFree)
- PlatformZapMem(blk,allocatedSize,0xDDDDDDDD);
-
- this->DoFree(blk);
-
- fBytesAllocated -= allocatedSize;
- fNumberAllocatedBlocks--;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::LargestFreeBlock
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- unsigned long MemoryHeap::LargestFreeBlock( ) const
- {
- long result = this->DoLargestFreeBlock();
- #if MM_DEBUG
- result -= this->CallAboutToAllocateHooks(0);
- #endif
- return result>0 ?result :0;
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetAutoValidation (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- Boolean MemoryHeap::GetAutoValidation() const
- {
- this->ValidateMagicNumber();
-
- return fAutoValidation;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetDescription
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- const char *MemoryHeap::GetDescription() const
- {
- this->ValidateMagicNumber();
-
- return fDescription;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetNextHeap
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHeap *MemoryHeap::GetNextHeap() const
- {
- return fNextHeap;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetZapOnAllocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- Boolean MemoryHeap::GetZapOnAllocate() const
- {
- this->ValidateMagicNumber();
-
- return fZapOnAllocate;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetZapOnFree
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- Boolean MemoryHeap::GetZapOnFree() const
- {
- this->ValidateMagicNumber();
-
- return fZapOnFree;
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::AdoptHook (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::AdoptHook(ODMemoryHook *memoryHook)
- {
- this->ValidateMagicNumber();
-
- fMemoryHookList.Add(memoryHook);
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::IsValidBlock (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- Boolean MemoryHeap::IsValidBlock(const void *blk) const
- {
- this->ValidateMagicNumber();
-
- if (blk == NULL)
- return false;
-
- blk = this->CallAboutToBlockSizeHooks(blk);
-
- if (this->IsMyBlock(blk))
- return DoIsValidBlock(blk);
- else
- return false;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::FindBlockContaining (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MMBoolean MemoryHeap::FindBlockContaining( const void *start, const void *end,
- const void* &blockStart, const void* &blockEnd ) const
- {
- this->ValidateMagicNumber();
-
- if( ! this->DoFindBlockContaining(start,end, blockStart,blockEnd) )
- return kMMFalse;
- else {
- if( blockStart ) {
- ODBlockSize hdrSize = this->CallGetHeaderSize();
- blockStart = (char*)blockStart + hdrSize;
- blockEnd = (char*)blockEnd - (this->CallAboutToAllocateHooks(0) - hdrSize);
- }
- return kMMTrue;
- }
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::NumberAllocatedBlocks
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- unsigned long MemoryHeap::NumberAllocatedBlocks() const
- {
- this->ValidateMagicNumber();
-
- return fNumberAllocatedBlocks;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetBlockIsObject
- //----------------------------------------------------------------------------------------
- void MemoryHeap::SetBlockIsObject( void* ptr, Boolean isObject )
- {
- this->ValidateMagicNumber();
- #if MM_DEBUG
- ptr = (void*) CallAboutToBlockSizeHooks(ptr);
- #endif
- this->DoSetBlockIsObject(ptr,isObject );
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::BlockIsObject
- //----------------------------------------------------------------------------------------
- Boolean MemoryHeap::BlockIsObject( const void* ptr ) const
- {
- this->ValidateMagicNumber();
- #if MM_DEBUG
- ptr = CallAboutToBlockSizeHooks(ptr);
- #endif
- return this->DoBlockIsObject(ptr);
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetBlockStackCrawl
- //----------------------------------------------------------------------------------------
- void MemoryHeap::SetBlockStackCrawl( const void* blk, StackCrawl *s )
- {
- this->ValidateMagicNumber();
- for (ODMemoryHook *hook = fMemoryHookList.Last();
- hook != NULL; hook = fMemoryHookList.Before(hook)) {
- blk = hook->AboutToBlockSize(blk);
- if( hook->GetType() == CBlockStackCrawlHook::kBlockStackCrawlHookType ) {
- ((CBlockStackCrawlHook*)hook)->SetStackCrawl(blk,s);
- return;
- }
- }
- MM_WARN("No BlockStackCrawlHook for SetBlockStackCrawl");
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetBlockStackCrawl
- //----------------------------------------------------------------------------------------
- StackCrawl* MemoryHeap::GetBlockStackCrawl( const void* blk ) const
- {
- this->ValidateMagicNumber();
- for (ODMemoryHook *hook = fMemoryHookList.Last();
- hook != NULL; hook = fMemoryHookList.Before(hook)) {
- blk = hook->AboutToBlockSize(blk);
- if( hook->GetType() == CBlockStackCrawlHook::kBlockStackCrawlHookType ) {
- return ((CBlockStackCrawlHook*)hook)->GetStackCrawl(blk);
- }
- }
- MM_WARN("No BlockStackCrawlHook for GetBlockStackCrawl");
- return NULL;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::GetBlockHeap
- //----------------------------------------------------------------------------------------
- MemoryHeap* MemoryHeap::GetBlockHeap( const void* ptr ) const
- {
- // This makes the assumption (in a debug build) that the block's heap
- // has the same memory hooks installed as this one. In reality this is the
- // case; but at some future point it might cause trouble......
- // In any case this will not occur in a non-debug build.
-
- this->ValidateMagicNumber();
- #if MM_DEBUG
- ptr = this->CallAboutToBlockSizeHooks(ptr);
- #endif
- return this->DoGetBlockHeap(ptr);
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::Reallocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::Reallocate(void *blk, ODBlockSize newSize)
- {
- this->ValidateMagicNumber();
-
- if (blk == NULL)
- return this->Allocate(newSize);
-
- ODBlockSize allocatedSize;
- ODBlockSize oldBlkSize = (ODBlockSize) this->BlockSize(blk);
-
- #if MM_DEBUG
- void *oldBlk = blk;
- this->CallAboutToReallocHooks(blk, newSize);
- #endif
-
- blk = this->DoReallocate(blk, newSize, allocatedSize);
-
- if (blk != NULL)
- fBytesAllocated += allocatedSize - oldBlkSize;
-
- #if MM_DEBUG
- blk = this->CallDidReallocHooks(oldBlk,blk, newSize);
- #endif
-
- return blk;
- }
-
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::AllocateSlushFund
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
- MMBoolean MemoryHeap::AllocateSlushFund( size_t size, size_t allocSizeLimit )
- {
- if( size==0 ) {
- this->FreeSlushFund();
- return kMMTrue;
- }
- this->Free(fSlushFund);
- size_t oldLimit = fSlushFundAllocSizeLimit;
- fSlushFundAllocSizeLimit = 0;
- MMBlock slushy = this->Allocate(size);
- if( !slushy ) {
- if( fSlushFund ) {
- fSlushFund = this->Allocate(fSlushFundSize);
- if( !fSlushFund )
- MM_WARN("Yow! Lost slush fund accidentally");
- }
- return kMMFalse;
- }
- fSlushFund = slushy;
- fSlushFundSize = size;
- fSlushFundAllocSizeLimit = allocSizeLimit;
- return kMMTrue;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::FreeSlushFund
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
- size_t MemoryHeap::FreeSlushFund( )
- {
- this->Free(fSlushFund);
- fSlushFund = kMMNULL;
- size_t size = fSlushFundSize;
- fSlushFundSize = fSlushFundAllocSizeLimit = 0;
- return size;
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::DeleteHook (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::DeleteHook(ODMemoryHook *memoryHook)
- {
- this->ValidateMagicNumber();
-
- fMemoryHookList.Remove(memoryHook);
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::Reset
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::Reset()
- {
- this->ValidateMagicNumber();
-
- #if MM_DEBUG
- this->CallAboutToResetHooks();
- #endif
-
- fBytesAllocated = 0;
- fNumberAllocatedBlocks = 0;
-
- this->DoReset();
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetAutoValidation (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::SetAutoValidation(Boolean autoValidation)
- {
- this->ValidateMagicNumber();
-
- fAutoValidation = autoValidation;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetDescription
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::SetDescription(const char *description)
- {
- this->ValidateMagicNumber();
-
- // ------ Set the description without depending on other code
-
- const char *src = description;
- char *dst = fDescription;
- int i;
-
- for (i = 0; i < kDescriptionLength - 1 && *src; i++)
- *dst++ = *src++;
- fDescription[i] = 0;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetZapOnAllocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::SetZapOnAllocate(Boolean zapOnAllocate)
- {
- this->ValidateMagicNumber();
-
- fZapOnAllocate = zapOnAllocate;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::SetZapOnFree
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::SetZapOnFree(Boolean zapOnFree)
- {
- this->ValidateMagicNumber();
-
- fZapOnFree = zapOnFree;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::~MemoryHeap
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHeap::~MemoryHeap()
- {
- this->ValidateMagicNumber();
-
- // ----- Remove from the static list of heaps
-
- MemoryHeap *lastHeap = NULL, *currentHeap = fHeapList;
-
- while (currentHeap != NULL)
- {
- if (this == currentHeap)
- {
- if (lastHeap == NULL)
- fHeapList = currentHeap->GetNextHeap();
- else
- lastHeap->fNextHeap = currentHeap->GetNextHeap();
-
- currentHeap = NULL;
- }
- else
- {
- lastHeap = currentHeap;
- currentHeap = currentHeap->GetNextHeap();
- }
- }
-
- // ------ Set the default description without depending on other code
-
- const char *src = kDeadHeapDescription;
- char *dst = fDescription;
- for (; *src;)
- *dst++ = *src++;
- *dst = 0;
-
- fMagicNumber = 0;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::MemoryHeap
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- MemoryHeap::MemoryHeap(Boolean autoValidation,
- Boolean zapOnAllocate,
- Boolean zapOnFree,
- MMHeapLocation memSrc) :
- fAutoValidation(autoValidation),
- fZapOnAllocate(zapOnAllocate),
- fZapOnFree(zapOnFree),
- fBytesAllocated(0),
- fNumberAllocatedBlocks(0),
- fMemSource(memSrc),
- fMagicNumber(kMagicNumber),
- fSlushFund(kMMNULL),
- fSlushFundSize(0),
- fSlushFundAllocSizeLimit(0)
- {
- // ------ Set the default description without depending on other code
-
- const char *src = kDefaultDescription;
- char *dst = fDescription;
- for (; *src;)
- *dst++ = *src++;
- *dst = 0;
-
- // Add to the static list of heaps
-
- fNextHeap = fHeapList;
- fHeapList = this;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::operator new
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void* MemoryHeap::operator new(SIZE_T size, MMHeapLocation src)
- {
- return PlatformAllocateBlock(size, src);
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::operator delete
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::operator delete(void* ptr)
- {
- PlatformFreeBlock(ptr);
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::AllocateRawMemory
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::AllocateRawMemory(ODBlockSize size)
- {
- return PlatformAllocateBlock(size, fMemSource);
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::DoReallocate
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::DoReallocate(void *block, ODBlockSize newSize, ODBlockSize &allocatedSize)
- {
- ODBlockSize oldRealSize = this->DoBlockSize(block);
- void* newBlock = this->DoAllocate(newSize, allocatedSize);
-
- if (newBlock != NULL)
- {
- ODBlockSize copySize = newSize <= oldRealSize ? newSize : oldRealSize;
- PlatformCopyMemory(block, newBlock, copySize);
-
- if (fZapOnFree)
- {
- char *chrBlk = (char *) block;
- for (ODBlockSize i = 0; i < oldRealSize; i++)
- *chrBlk++ = 0xDD;
- }
-
- this->DoFree(block);
- }
- else
- if (newSize <= oldRealSize) //if unable to get new fMem, and newSize is <= real size
- return block; //then return original ptr unchanged
-
- return newBlock;
- }
-
- //----------------------------------------------------------------------------------------
- // MemoryHeap::FreeRawMemory
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::FreeRawMemory(void* ptr)
- {
- PlatformFreeBlock(ptr);
- }
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CompilerCheck (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::CompilerCheck()
- {
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallAboutToAllocateHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODBlockSize MemoryHeap::CallAboutToAllocateHooks(ODBlockSize size) const
- {
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook))
- size = hook->AboutToAllocate(size);
-
- return size;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallGetHeaderSize (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- ODBlockSize MemoryHeap::CallGetHeaderSize() const
- {
- ODBlockSize size = 0;
-
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook))
- size += hook->GetHeaderSize();
-
- return size;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallDidAllocateHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::CallDidAllocateHooks(void* blk, ODBlockSize size)
- {
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook)) {
- blk = hook->DidAllocate(blk, size);
- size -= hook->AboutToAllocate(0);
- }
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallAboutToBlockSizeHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- const void *MemoryHeap::CallAboutToBlockSizeHooks(const void* blk) const
- {
- for (ODMemoryHook *hook = fMemoryHookList.Last();
- hook != NULL; hook = fMemoryHookList.Before(hook))
- blk = hook->AboutToBlockSize(blk);
-
- return (void*) blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallAboutToFreeHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::CallAboutToFreeHooks(void* blk)
- {
- for (ODMemoryHook *hook = fMemoryHookList.Last();
- hook != NULL; hook = fMemoryHookList.Before(hook))
- blk = hook->AboutToFree(blk);
-
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallAboutToReallocHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::CallAboutToReallocHooks(void* &blk, ODBlockSize& size)
- {
- for (ODMemoryHook *hook = fMemoryHookList.Last();
- hook != NULL; hook = fMemoryHookList.Before(hook))
- hook->AboutToRealloc(blk, size);
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallDidReallocHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void *MemoryHeap::CallDidReallocHooks(void *oldBlk, void *blk, ODBlockSize size)
- {
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook)) {
- blk = hook->DidRealloc(oldBlk, blk, size);
- size -= hook->AboutToAllocate(0);
- }
- return blk;
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallAboutToResetHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::CallAboutToResetHooks()
- {
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook))
- hook->AboutToReset();
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::CallCommentHooks (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::CallCommentHooks(const char* comment)
- {
- for (ODMemoryHook *hook = fMemoryHookList.First();
- hook != NULL; hook = fMemoryHookList.After(hook))
- hook->Comment(comment);
- }
- #endif
-
- #if MM_DEBUG
- //----------------------------------------------------------------------------------------
- // MemoryHeap::ValidateAndReport (MM_DEBUG only)
- //----------------------------------------------------------------------------------------
- #pragma segment HeapSeg
-
- void MemoryHeap::ValidateAndReport(void *blk) const
- {
- MM_ASSERT(this->IsValidBlock(blk));
- }
- #endif
-